/*
 * battleship.cpp
 *
 *  Created on: Jul 22, 2013
 *      Author: Socrates Frangis (soc.frangis@gmail.com)
 */

#include <iostream>
#include <cstdlib>
#include <ctime>
using namespace std;

const int depth = 2;
const int length = 10;
char grid[depth][length][length];
int i, j, k;

void createGrid(){
	for(i = 0; i < 4; i++){
		for(j=0; j < 10; j++){
			for(k=0; k < 10; k++){
				grid[i][j][k] = '~';
			}
		}
	}
}

void printGrid(int i){
	//Print the Column Header
	cout << "* 0 1 2 3 4 5 6 7 8 9" << endl;

	//Print the Grid
	for(j=0; j < length; j++){

		cout << j << " ";

		//Print the Tile
		for(k=0; k < length; k++){
			cout << grid[i][j][k] << " ";
		}

		cout << endl;
	}
}

int validatePlacement(int player, int size, char direction, int row, int col){
	bool validGridBounds = true;
	bool validShipClipping = true;

	//Input Validation to prevent placing ship out of bounds
	switch(direction){
		case 'U': if(row - size < -1) validGridBounds = false; break;
		case 'D': if(row + size > 10) validGridBounds = false; break;
		case 'L': if(col - size < -1) validGridBounds = false; break;
		case 'R': if(col + size > 10) validGridBounds = false; break;
	}

	//Input validation to prevent overwriting other ships
	switch(direction){//make sure its water(~) && that I'm not checking beyond the grid bounds
		case 'U':
			for(int i=0; i < size; i++){if((grid[player][row - i][col] != '~') && (row - i >= 0))
				validShipClipping = false;}break;

		case 'D':
			for(int i=0; i < size; i++){if((grid[player][row + i][col] != '~') && (row + i <= 9))
				validShipClipping = false;}break;

		case 'L':
			for(int i=0; i < size; i++){if((grid[player][row][col - i] != '~') && (col - i >= 0))
				validShipClipping = false;}break;

		case 'R':
			for(int i=0; i < size; i++){if((grid[player][row][col + i] != '~') && (col + i <= 9))
				validShipClipping = false;}break;
	}
	if(validGridBounds && validShipClipping) return 0;
	else if (!validGridBounds && validShipClipping) return 1;
	else if (validGridBounds && !validShipClipping) return 2;
	else return 3; //!validGridBounds && !validShipClipping
}

void placeUserShips(char shipType){
	int row, col, size, validationResult;
	char direction;
	string type;

	//determine ship size & type
	switch(shipType){
		case 'F': size = 2; type = "Frigate";	break;
		case 'D': size = 3; type = "Destroyer"; break;
		case 'S': size = 3; type = "Submarine"; break;
		case 'B': size = 4; type = "Battleship";break;
		case 'C': size = 5; type = "Carrier";	break;
	}

	do{
		//Show the grid
		cout << endl;
		printGrid(0);
		cout << endl;

		//Prompt for input
		cout << endl << "Place a " << type << " (" << size << ")" << endl;
		cout << "Row: ";
		cin  >> row;
		cout << "Column: ";
		cin  >> col;
		cout << "Direction (U,D,L,R): ";
		cin  >> direction;

		//Add input validation handling to change case from lower to UPPER (e.g. u,d,l,r -> U,D,L,R)
		//TODO


		validationResult = validatePlacement(0,size,direction,row,col);

		switch(validationResult){
			case 0: break;
			case 1: cout << "Error: Ship out of bounds" << endl; break;
			case 2: cout << "Error: Ship overlaps an already placed ship" << endl; break;
			case 3: cout << "Error: Ship out of bounds and overlaps another ship" << endl; break;
		}
	}while(validationResult > 0);

	//Ship has valid placement coordinates, now place initial ship pivot
	grid[0][row][col] = shipType;

	//Ship has valid placement coordinates, now place remainder of ship
	int count = 1;
	do{
		switch(direction){
			case 'U':
				grid[0][row-count][col] = shipType;
				break;
			case 'D':
				grid[0][row+count][col] = shipType;
				break;
			case 'L':
				grid[0][row][col-count] = shipType;
				break;
			case 'R':
				grid[0][row][col+count] = shipType;
				break;
		}
		count++;
	}while (count < size);
}

void placeComputerShips(){
	//Randomly seed the counter based on time
	srand((unsigned)time(0));
	int randomRow, randomCol, randomDir, validationResult, size;
	char direction;
	char ships[] = {'F','D','S','B','C'};
	int  sizes[] = {  2,  3,  3,  4,  5};
	char shipType;

	for(int i = 0; i < 5; i++){
		do{
			size = sizes[i];
			shipType = ships[i];

			//Generate Random Row, Column, and Placement Direction
			randomRow = (rand()%9);
			randomCol = (rand()%9);
			randomDir = (rand()%4);

			//Translate direction to a char
			switch(randomDir){
				case 0 : direction = 'U'; break;
				case 1 : direction = 'D'; break;
				case 2 : direction = 'L'; break;
				case 3 : direction = 'R'; break;
			}
			validationResult = validatePlacement(1, size, direction, randomRow, randomCol);
		}while(validationResult > 0);

		int row = randomRow;
		int col = randomCol;
		int count = 1;

		//Ship has valid placement coordinates, now place initial ship pivot
		grid[1][row][col] = shipType;

		do{
			switch(direction){
				case 'U':
					grid[1][row-count][col] = shipType;
					break;
				case 'D':
					grid[1][row+count][col] = shipType;
					break;
				case 'L':
					grid[1][row][col-count] = shipType;
					break;
				case 'R':
					grid[1][row][col+count] = shipType;
					break;
			}
			count++;
		}while (count < size);
	}
}

void playGame(){
	int userShipCount = 17;
	int compShipCount = 17;

	//Initialize hit tracking grids for player and computer
	//TODO

	do{
		//Show Player Grid
		//TODO

		//Show Opponent Grid
		//TODO

		//Prompt user to shoot
		//TODO

		//Determine hit or miss, decrement computerShipCount if hit
		//TODO

		//Determine if individual ship has sunk
		//TODO

		//Update grid that displays hits on the computer to the user
		//TODO

		//Have computer shoot, right now AI is stupid and just randomly shoots
		//TODO

		//Determine hit or miss, decrement userShipCount if hit
		//TODO

		//Update grid that displays hits on the user to the user
		//TODO

	}while (userShipCount > 0 && compShipCount > 0);
	if(userShipCount == 0) cout << "GAME OVER, YOU LOSE!!!";
	else cout << "CONGRADULATIONS, YOU WON!!!";
}

int main(){
	//Initial Setup
	createGrid();
	cout << endl;

	//Place User Ships
	//TODO Make a loop within placeUserShips to handle all ship types
	//TODO Make a single function for inserting ship, reduce copy/pasted code
	placeUserShips('F');
	placeUserShips('D');
	placeUserShips('S');
	placeUserShips('B');
	placeUserShips('C');
	cout << endl;
	printGrid(0);

	//Place Opponent Ships
	placeComputerShips();
	cout << endl;
	printGrid(1);

	//Start the Game
	playGame();
}



